package com.computerManagementSystem.util;
import com.auth0.jwt.*;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.interfaces.DecodedJWT;


import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 赖志宇
 * @date 2020/6/16 23:42
 */
public class JWTUtil {
    private static final String SECRET = "JIWEI123456";
    private static final long loginExpireTime = 7*24 * 60 * 60 * 1000;
    private static final String ISSUER = "www.jiwei.com";
    private static Algorithm algorithm = Algorithm.HMAC256(SECRET);

    /**
     * 创建一个凭证
     * @param name 凭证荷载的名称
     * @param value 凭证荷载名称对应的值
     * @return token字符串
     */
    public static  String createToken(String name, String value) {
        long currentTimeMillis = System.currentTimeMillis();
        long expireTime = loginExpireTime;
        if("role".equals(name))
            expireTime = 1000*60*60;
        Date expireDate = new Date(currentTimeMillis + expireTime);
        Map<String, Object> headerClaims = new HashMap<String, Object>(2);
        headerClaims.put("alg", "HS256");
        headerClaims.put("typ", "JWT");
        try {
            return JWT.create().withHeader(headerClaims)
                    .withIssuer(ISSUER)
                    .withIssuedAt(new Date(currentTimeMillis))
                    .withExpiresAt(expireDate)
                    .withClaim(name, value)
                    .sign(algorithm);
        } catch (JWTCreationException exception) {
            return null;
        } catch (Exception e) {
            return null;
        }


    }

    /**
     * 创建一个登录凭证
     * @param value 成员id或机主手机号
     * @return 加密过的字符串
     */
    public static String createLoginToken(String value){
       return createToken("account",value);
    }

    /**
     * 创建一个权限凭证
     * @param value 权限
     * @return 加密的token
     */
    public static String createRoleToken(String value){
        return createToken("role",value);
    }
    /**
     * 解析token 获得一个decodedJWT对象，目前没什么用，职责分离是为了给以后的开发修改时提供便利
     * @param token 加密过得字符串，里面荷载了一些用户信息
     * @return JWT对象
     */
    public static DecodedJWT parseToken(String token) {
        try {
            JWTVerifier jwtVerifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            DecodedJWT jwt = jwtVerifier.verify(token);
            return jwt;
        }
        catch (Exception exception) {
            //exception.printStackTrace();
            return null;
        }


    }

    /**
     * 验证token是否正确
     * @param token
     * @return
     */
    public static Boolean verifyToken(String token){
        if(parseToken(token)!=null)
            return true;
        else
            return false;
    }

    /**
     * 通过名字获取value
     * @param token 加密的字符串
     * @param name  需要获取的荷载信息名称
     * @return
     */
    public static String getClaim(String token,String name){
       //还可以这样写，但我发现了一个自带的方法
        DecodedJWT jwt = parseToken(token);

        if(jwt!=null){
            return jwt.getClaim(name).asString();
        }

        else
            return null;
      /*if(token==null)
           return null;
        return JWT.decode(token).getClaim(name).asString();*/
    }

    /**
     * 取得名为account的值，即账号
     * @param token
     * @return
     */
    public static String getClaimNamedAccount(String token){
        return getClaim(token,"account");
    }

    public static String getClaimNamedRole(String token){
        return getClaim(token,"role");
    }
    /**
     * 获取一个新的凭证
     * @param token 加密后的字符串
     * @return 新的加密字符串
     */
    public static String createNewToken(String token,String name){
        String value = getClaim(token,name);
        return createToken(name,value);
    }
}
